/**
 ******************************************************************************
 * @file	do_shell.c
 * @brief	TR700-STM32的内部命令

- 2017-6-23,MenglongWu,MenglongWoo@aliyun.com
 *
 Copyright (C) 2017 桂林聚联科技有限公司, Inc. All Rights Reserved.
*/

#include <autoconfig.h>
#include <stdio.h>
#include <string.h>
#include <minishell-tiny.h>
#include <prj_type.h>
#include <TR700Driver.h>
#include <project.h>
#include "printl.h"
#include <math.h>
#include <unos_input.h>


// led ls on
// led opm on
#ifdef CONFIG_DO_LED
int do_led (void *ptr, int argc, char **argv)
{
	int index = 0;
	int status = 0;

	if (argc < 3) {
		printf("Uarge:\r\n"
		       "\tled <name> <status>\r\n"
		       "\tname  :\tls/opm\r\n"
		       "\tstatus:\ton/off\r\n");
		return -1;
	}


	switch (argv[1][0]) {
	case 'l': // led ls xxx
		index = CTRL_LED_LS;
		break;
	case 'o': // led opm xxx
		index = CTRL_LED_OPM;
		break;
	default:
		return -1;
	}

	switch (argv[2][1]) {
	case 'n': // led xxx on
		status = LED_ON;
		break;
	case 'f': // led xxx off
		status = LED_OFF;
		break;
	default:
		return -1;
	}
	Ctrl_LED(index, status);
}
#endif

#ifdef CONFIG_DO_DAC
int do_dac (void *ptr, int argc, char **argv)
{
	struct device_ls v;
	if (argc < 2) {
		return -1;
	}

	v.dac = atoi(argv[1]);
	// g_power.dac = v.dac;
	dev_ls.dac = v.dac;
	Ctrl_LaserDAC(&v);
}
#endif

#ifdef CONFIG_DO_LASER
int do_laser (void *ptr, int argc, char **argv)
{
	int mode = 0;
	int str_modelen;

	if (argc < 3) {
		printf("Uarge:\r\n"
		       "\tlaser <ch> <mode>\r\n"
		       "\tch  :\t1/2/3\r\n"
		       "\tmode:\tcw/270/1k/2k\r\n");
		return -1;
	}

	str_modelen = strlen(argv[2]);
	// laser chn mode

	// printf("len argv[2] %d %x %x %x\r\n", strlen(argv[2]), argv[2][strlen(argv[2]) - 1], '\n', '\r');
	if (0 == memcmp(argv[2], "cw", str_modelen)) {
		mode = LASER_MODE_CW;
	} else if (0 == memcmp(argv[2], "270\r", str_modelen)) {
		mode = LASER_MODE_270Hz;
	} else if (0 == memcmp(argv[2], "1k", str_modelen)) {
		mode = LASER_MODE_1KHZ;
	} else if (0 == memcmp(argv[2], "2k\r", str_modelen)) {
		mode = LASER_MODE_2KHZ;
	}
	dev_ls.ch    = atoi(argv[1]);
	dev_ls.mode  = mode;
	Ctrl_LaserMode(&dev_ls);
	Ctrl_LaserChannel(&dev_ls);
}
#endif


#ifdef CONFIG_DO_OPM
int do_opm(void *ptr, int argc, char **argv)
{
	int index = 0;

	if (argc < 2) {
		return -1;
	}
	Ctrl_OPM_SW(atoi(argv[1]));
}
#endif
void draw_title(char *title)
{
	int i;

	printf("\r\n"), printf("\r\n");
	for (i = 0; i < 78; i++) {
		printf("*");
	}
	printf("\r\n");
	printf("\t%s\r\n", title);
	for (i = 0; i < 78; i++) {
		printf("*");
	}
	printf("\r\n");

}
void draw_line(int count, int br)
{
	int i;
	for (i = 0; i < count; i++) {
		printf("-");
	}
	if (br) {
		printf("\r\n");
	}
}

void draw_space(int count, int br)
{
	int i;
	for (i = 0; i < count; i++) {
		printf(" ");
	}
	if (br) {
		printf("\r\n");
	}
}
void show_ls()
{
	draw_title("LS Adjust");
	printf("SN:%s\r\n", g_adj_power.sn);

	printf("adj_point :  CH(n) ADC    :  CH(n) DAC\r\n");
	draw_line(40, 1);
	printf("-10dBm    | ch1-adc  %4.0f  |  ch1-dac %4.0f\r\n", g_adj_power._adc1, g_adj_power._dac1);
	printf("-10dBm    | ch2-adc  %4.0f  |  ch2-dac %4.0f\r\n", g_adj_power._adc2, g_adj_power._dac2);
	printf("-10dBm    | ch3-adc  %4.0f  |  ch3-dac %4.0f\r\n", g_adj_power._adc3, g_adj_power._dac3);

#ifdef CONFIG_ADJ_N5DBM
	printf("-5dBm     | ch1-adc  %4.0f  |  ch1-dac %4.0f\r\n", g_adj_power._5_adc1, g_adj_power._5_dac1);
	printf("-5dBm     | ch2-adc  %4.0f  |  ch2-dac %4.0f\r\n", g_adj_power._5_adc2, g_adj_power._5_dac2);
	printf("-5dBm     | ch3-adc  %4.0f  |  ch3-dac %4.0f\r\n", g_adj_power._5_adc3, g_adj_power._5_dac3);
	printf("\r\n");
#endif
	// printf("Ch(n)    :      enable    :  alias\r\n");
	// printf("ch1      |       %2s      |  %4d\r\n", g_adj_power.en_ch1 ? "En" : "No" , g_adj_power._ch1wave);
	// printf("ch2      |       %2s      |  %4d\r\n", g_adj_power.en_ch2 ? "En" : "No" , g_adj_power._ch2wave);
	// printf("ch3      |       %2s      |  %4d\r\n", g_adj_power.en_ch3 ? "En" : "No" , g_adj_power._ch3wave);
}




struct show_opm_private {
	unsigned short *low;
	unsigned short *high;
	int min_dbm;
};
void show_opm()
{
	int i;
	struct show_opm_private list[] = {
		{&g_adj_power.lv1_low, &g_adj_power.lv1_high, 5 - OPT_OFFSET},
		{&g_adj_power.lv2_low, &g_adj_power.lv2_high, -5 - OPT_OFFSET},
		{&g_adj_power.lv3_low, &g_adj_power.lv3_high, -15 - OPT_OFFSET},
		{&g_adj_power.lv4_low, &g_adj_power.lv4_high, -25 - OPT_OFFSET},
		{&g_adj_power.lv5_low, &g_adj_power.lv5_high, -35 - OPT_OFFSET},
		{&g_adj_power.lv6_low, &g_adj_power.lv6_high, -45 - OPT_OFFSET},
		{&g_adj_power.lv7_low, &g_adj_power.lv7_high, -55 - OPT_OFFSET},
	};

	/*
	********************************************************************************
	    OPM
	******************************************************************************
	      400       5dBm       0
	LV1    |---------|---------|
	      400      -5dBm       0
	LV2    |---------|---------|
	      400     -15dBm    4000
	LV3    |---------|---------|
	      400     -25dBm    4000
	LV4    |---------|---------|
	      400     -35dBm    4000
	LV5    |---------|---------|
	      400     -45dBm    4000
	LV6    |---------|---------|
	      400     -55dBm    4000
	LV7    |---------|---------|
	*/
	draw_title("OPM Adjust");
	for (i = 0; i < ARRAY_SIZE(list); i++) {
		// draw_space(21 * (ARRAY_SIZE(list) -  i), 0);
		printf("  %4ddBm   %4ddBm    %4ddBm\r\n",
		       list[i].min_dbm - 5,  list[i].min_dbm, list[i].min_dbm + 5);
		// draw_space(21 * (ARRAY_SIZE(list) -  i - 1), 0);
		printf("    %4d                 %4d\r\n",
		       *list[i].low,  *list[i].high);
		// draw_space(21 * (ARRAY_SIZE(list) -  i-1), 0);
		if (i == 5) {
			printf(" LV%d    |---------|---------|\t\t"C_RED"[Fail]"C_NORMAL"\r\n\r\n", i + 1);
		} else {
			printf(" LV%d    |---------|---------|\t\t"C_GREEN"[OK]"C_NORMAL"\r\n\r\n", i + 1);
		}
	}

	draw_title("OPM measure range");
	for (i = 0; i < ARRAY_SIZE(list) - 1; i++) {
		printf("	          %6.2f %4d                %4d\r\n",
		       (float)(list[i].min_dbm - 5 + 10 * log10(LOW_PRESENT)),
		       list[i].min_dbm - 5,
		       list[i].min_dbm + 5);
		printf(C_CYAN "LV%d" C_NORMAL "                  ------|---------|---------|\r\n", i + 1);
		printf("LV%d    ....    --|---------|\r\n\r\n", i + 2);
	}

}

int do_show (void *ptr, int argc, char **argv)
{
	show_ls();
	show_opm();
	return 0;
}

#define CUI_SELECT (C_CYAN AC_REVERSE)
#define CUI_NORMAL (C_NORMAL)
#define CUI_HIGHLIGHT (C_CYAN)
#if 0
struct _draw_ls_private {
	float          *dbm;
	int             *mode;
	int             *ch;
	unsigned short *s_adc;
	unsigned short *s_dac;
	unsigned short *c_adc;
	unsigned short *c_dac;
};
#define COUNT_CONTROL (3)
void _draw_ls(unsigned int select, void *v)
{
	struct _draw_ls_private *p = (struct _draw_ls_private *)v;
	char *c_item[COUNT_CONTROL]     = {C_NORMAL, C_NORMAL, C_NORMAL};
	char *strmode[LASER_MODE_COUNT] = {"cw", "270", "1k", "2k"};// TODO off
	char *strch[CTRL_CH_COUNT]      = {"-", "1", "2", "3"};// TODO off
	char *pmode;
	char *pch;

	c_item[select % ARRAY_SIZE(c_item)] = (C_CYAN AC_REVERSE);  // 高亮选中列
	pmode = strmode[(unsigned int) * (p->mode) % LASER_MODE_COUNT];
	pch   = strch  [(unsigned int) * (p->ch)   % CTRL_CH_COUNT];


	printf("  %s%6.2fdBm  "
	       "%s%3s  "
	       "%sCh%s   "
	       C_NORMAL "ADCs:%4d  "
	       "DACs:%4d  "
	       "ADCc:%4d  "
	       "DACc:%4d\r",

	       c_item[0], *(p->dbm),
	       c_item[1], pmode,
	       c_item[2], pch,
	       *(p->s_adc),
	       *(p->s_dac),
	       *(p->c_adc),
	       *(p->c_dac));
}

void _watch_ls_key(unsigned int *select, void *v, int key)
{
	struct _draw_ls_private *p = (struct _draw_ls_private *)v;
	static int times = 0;

	int   deta       = 1;
	float deta_dbm   = 0.01;
	int tmp;


	if (is_fastkeydown(key)) {
		if (times++ >= 8) {
			deta = 10;
			deta_dbm = 0.10;
		}
	} else {
		times = 0;
		deta = 1;
		deta_dbm = 0.01;
	}

	switch (key) {
	case VK_DOWN:
	case 's':
		deta_dbm  = -deta_dbm;
		deta      = -deta;
	case VK_UP:
	case 'w':
		switch( (unsigned int)(*select) % COUNT_CONTROL ) {
		case 0: // dbm
			*(p->dbm)   += deta_dbm;
			if (*(p->dbm) > COUNT_CONTROL) {
				*(p->dbm) = -20;
			} else if (*(p->dbm) < -20) {
				*(p->dbm) = 3;
			}
			break;
		case 1: // mode
			*(p->mode) += deta;
			*(p->mode) = (unsigned int) * (p->mode) % LASER_MODE_COUNT;
			break;
		case 2: // ch
			*(p->ch) += deta;
			*(p->ch) = (unsigned int) * (p->ch) % CTRL_CH_COUNT;
			break;
		default:
			break;
		}
		break;
	case VK_RIGHT:
		(*select)++;
		break;
	case VK_LEFT:
		(*select)--;
		break;
	default:
		break;
	}



}

void watch_ls()
{
	int times = 0;
	int deta = 0;
	unsigned long after;
	unsigned short adc;
	unsigned long task_update_dac;
	float dbm = -10;
	float deta_dbm = 0;
	unsigned int select = 1000 * COUNT_CONTROL;// 多少都无所谓，只不过如果设置为0
	unsigned long task_readkey;
	int i;
	int key = 0;
	struct _draw_ls_private draw;
	unsigned short unuse = 0;
	int mode = LASER_MODE_CW;
	int ch = CTRL_CH1;
	task_update_dac = jiffies + 100 * _1MS;
	task_readkey = jiffies + 1 * _1MS;


	draw.dbm   = &dbm;
	draw.mode  = &mode;
	draw.ch    = &ch;
	draw.s_dac = &unuse;
	draw.s_adc = &g_power.adc;
	draw.s_dac = &unuse;
	draw.c_adc = &adc;
	draw.c_dac = &g_power.dac;

	while(key != 'q') {
		key = 0;
		if (time_after(jiffies, task_readkey)) {
			task_readkey = jiffies + 20 * _1MS;
			key = getkeycode();
			if (key > 0) {
				_watch_ls_key(&select, &draw, key);
				adc = GetAD(AD_CH_LS);
				g_power.adc = (uint16_t)((pow(10, (float)dbm / 10)) * g_adj_power._adc1 * 10);
				g_power.dac = (uint16_t)((pow(10, (float)dbm / 10)) * g_adj_power._dac1 * 10);
				Ctrl_LaserDAC(&g_power);
				_draw_ls(select, &draw);

			}
		}
		if (time_after(jiffies, task_update_dac)) {
			task_update_dac = jiffies + 100 * _1MS;
			adc = GetAD(AD_CH_LS);
			AutoCtrl_LS();
			_draw_ls(select, &draw);
		}
	}
	printf("\r\n");
}
#endif



extern void watch_ls();
extern void watch_opm();

int do_watch(void *ptr, int argc, char **argv)
{
	if (argc < 2) {
		return -1;
	}

	switch (argv[1][0]) {
	case 'l': // led ls xxx
		watch_ls();
		break;
	case 'o': // led opm xxx
		watch_opm();
		break;
	default:
		return -1;
	}

}

// 手工校准
int adj_ls(void *ptr, int argc, char **argv)
{
	int ch;
	int dbm;
	int adc;
	int dac;
	if (argc < 5) {
		printf("Uarge:\r\n\tls ch dBm mode adc dac\r\n");
		return -1;
	}

	// ls ch dBm adc dac


	ch = atoi(argv[1]);
	if (0 == strcmp(argv[2], "-5")) {
		dbm = -5;
	} else if (0 == strcmp(argv[2], "-10")) {
		dbm = -10;
	} else {
		return -1;
	}
	adc = atoi(argv[3]);
	dac = atoi(argv[4]);


	switch(ch) {
	case 1:
		g_adj_power._adc1 = adc;
		g_adj_power._dac1 = dac;
		break;
	case 2:
		g_adj_power._adc2 = adc;
		g_adj_power._dac2 = dac;
		break;
	case 3:
		g_adj_power._adc3 = adc;
		g_adj_power._dac3 = dac;
		break;
	default:
		return -1;
	}

}




/**
 * @brief	按键长按
 * @param	null
 * @retval	null
 * @remarks
 * @see
 */

int is_fastkeydown(int key)
{

#define FAST_KEYDOWN_DETA (100 * _1MS)

	static int lastkey = 0;
	static unsigned long last_keydown;
	int ret;

	if (lastkey != key) {
		lastkey = key;
		return 0;
	}

	if (last_keydown - jiffies < (-FAST_KEYDOWN_DETA) ) {
		ret = 0;
	} else {
		ret = 1;
	}
	last_keydown = jiffies;
	return ret;
}

int ui_ls(unsigned short *pt)
{
	unsigned long task_update_dac;
	char buf[2];
	int len = 0;
	unsigned short adc = 0;
	unsigned long deta = 1;
	int times = 0;

	printf(C_CYAN
	       "[q]:Quit   [y]:adjust  "
	       "[w/up]:DAC +1 or +10  "
	       "[s/down]:DAC -1 or -10\r\n"
	       C_NORMAL);
	buf[0] = '1';
	task_update_dac = jiffies + 1000 * _1MS;

	while(buf[0] != 'q' && buf[0] != 'y') {



		// len = CommRead(buf, 1);
		len = ReadUart(buf, 1);



		if (len > 0) {
			if (is_fastkeydown(buf[0])) {
				if (times++ >= 8) {
					deta = 10;
				}
			} else {
				times = 0;
				deta = 1;
			}
			switch (buf[0]) {
			case 'w':
				// g_power.dac++;
				dev_ls.dac += deta;
				len = 0;
				break;
			case 's':
				// dev_ls.dac--;
				dev_ls.dac -= deta;
				len = 0;
				break;
			default:
				break;
			}
			if ((short)dev_ls.dac > 4095) {
				dev_ls.dac = 0;
			} else if((short)dev_ls.dac  < 0) {
				dev_ls.dac  = 4095;
			}
			Ctrl_LaserDAC(&dev_ls);

			printf("ADC:%4d     " C_CYAN "DAC:%4d\r" C_NORMAL,
			       adc, dev_ls.dac);
		}


		if (time_after(jiffies, task_update_dac)) {
			task_update_dac = jiffies + 100 * _1MS;
			adc = GetAD(AD_CH_LS);
			printf("ADC:%4d     " C_CYAN "DAC:%4d\r" C_NORMAL,
			       adc, dev_ls.dac);
			// AutoCtrl_LS();
		}
	}
	if (buf[0] == 'y') {
		*pt = adc;
		return 1;
	} else {
		return 0;
	}
}

struct one_key_ls_private {
	int ch;
	int dbm;
	unsigned short *adc;
	unsigned short *dac;
	int *wave;
};
void one_key_ls()
{
	int i;
	struct one_key_ls_private list[] = {
#if 0
		{1, -10, &g_adj_power._adc1, &g_adj_power._dac1, &g_adj_power._ch1wave},
		{2, -10, &g_adj_power._adc2, &g_adj_power._dac2, &g_adj_power._ch2wave},
		{3, -10, &g_adj_power._adc3, &g_adj_power._dac3, &g_adj_power._ch3wave},
#else
		{1, -10, &sys_param.ch1_10_adc, &sys_param.ch1_10_dac, &sys_param.ch1_wave},
		{2, -10, &sys_param.ch2_10_adc, &sys_param.ch2_10_dac, &sys_param.ch2_wave},
		{3, -10, &sys_param.ch3_10_adc, &sys_param.ch3_10_dac, &sys_param.ch3_wave},
#endif
		
#ifdef CONFIG_ADJ_N5DBM
		{1, -5, g_adj_power._5_adc1, &g_adj_power._5_dac1, &g_adj_power._ch1wave},
		{2, -5, g_adj_power._5_adc2, &g_adj_power._5_dac2, &g_adj_power._ch2wave},
		{3, -5, g_adj_power._5_adc3, &g_adj_power._5_dac3, &g_adj_power._ch3wave},
#endif
	};
	char strout[16];

	for (i = 0; i < ARRAY_SIZE(list); i++) {
		snprintf(strout, 16, "Ch%d(%d)\t%ddBm",
		         list[i].ch, 1310, list[i].dbm);
		draw_title(strout);

		if (ui_ls(list[i].adc)) {
			*list[i].dac = dev_ls.dac;
#ifndef NDEBUG
			printf("\r\n[ADC:%4.0d     DAC:%4.0d]\r",
			       *list[i].adc, *list[i].dac);
#endif
		}
	}

	show_ls();
}

int ui_opm(int lvA, int lvB, unsigned short *ptA, unsigned short *ptB)
{
#define DAT_100MS (80)
#define DAT_500MS (100)
	unsigned long after, _100ms, _500ms;
	char buf[2];
	int len = 0;
	int lv_current = lvA;
	unsigned short adcA = 10, adcB = 10;
	float dbmAlow = 0, dbmAhigh = 0, dbmBlow = 0, dbmBhigh = 0;


	Ctrl_OPM_SW(lvA);
	buf[0] = '1';
	_100ms = jiffies + DAT_100MS;
	_500ms = jiffies + DAT_500MS;
	while(buf[0] != 'q' && buf[0] != 'y') {
		// len = CommRead(buf, 1);
		len = ReadUart(buf, 1);

		// 每100ms观察其中一个档位值
		if (time_after(jiffies, _100ms)) {
			_100ms = jiffies + DAT_100MS;
			if (lv_current == lvA) {
				adcA     = GetAD(AD_CH_OPM);
				dbmAlow  = Calc_ADC2dBm(F_ADC2DBM_LOW, adcA);
				dbmAhigh = Calc_ADC2dBm(F_ADC2DBM_HIGH, adcA);
			} else {
				adcB = GetAD(AD_CH_OPM);
				dbmBlow  = Calc_ADC2dBm(F_ADC2DBM_LOW, adcB);
				dbmBhigh = Calc_ADC2dBm(F_ADC2DBM_HIGH, adcB);
			}
			printf("LV%d ADC:"C_CYAN"%4d"C_NORMAL"  (%6.2fdBm/%6.2fdBm)   "
			       "LV%d ADC:"C_CYAN"%4d"C_NORMAL"  (%6.2fdBm/%6.2fdBm)\r",
			       lvB, adcB, dbmBlow, dbmBhigh,
			       lvA, adcA, dbmAlow, dbmAhigh);
		}

		// 每次500ms来回切换档位
		if (time_after(jiffies, _500ms)) {
			_100ms = jiffies + DAT_100MS;
			_500ms = jiffies + DAT_500MS;
			if (lv_current == lvA) {
				Ctrl_OPM_SW(lvB);
				lv_current = lvB;
			} else {
				Ctrl_OPM_SW(lvA);
				lv_current = lvA;
			}

		}
	}
	printf("\r\n");
	if (buf[0] == 'y') {
		*ptA = adcA;
		*ptB = adcB;
		return 1;
	} else {
		return 0;
	}
}
unsigned short Lvn_OPM_ADC(int lv)
{
	Ctrl_OPM_SW(lv);
	// Delay_ms(50);
	GetAD(AD_CH_OPM);
	Delay_ms(1000);

	// Delay_ms(100);
	return GetAD(AD_CH_OPM);
}

void draw_2lv_range(int lvA, int lvB,
                    int maxA,
                    int mid,
                    int minB)
{
	printf("\r\n");
	printf("          Lv%d                      mid                  Lv%d\r\n",
	       lvB, lvA);
	printf("%4ddBm                         " C_CYAN "%4ddBm" C_NORMAL "                     %4ddBm\r\n",
	       minB, mid, maxA);

	// printf("          Lv%d                      mid                  Lv%d\r\n",
	// 	lvA, lvB);
	// printf("%4ddBm                           %4ddBm                     %4ddBm\r\n",
	// 	maxA, mid, minB);
	printf("\r\n");
}
void one_key_opm()
{
	draw_line(40, 1);

	// printf("Lv1 Lv2  (-2dBm)\r\n\r\n");
	draw_2lv_range(1, 2, 0 - OPT_OFFSET + 10, 0 - OPT_OFFSET, 0 - OPT_OFFSET - 10);
	if (ui_opm(1, 2, &sys_param.lv1_low, &sys_param.lv2_high)) {
		printf("%4d %4d\r\n", sys_param.lv2_high, sys_param.lv1_low);
	}
	draw_line(40, 1);
	// printf("Lv2 Lv3  (-12dBm)\r\n\r\n");
	draw_2lv_range(2, 3, -10 - OPT_OFFSET + 10, -10 - OPT_OFFSET, -10 - OPT_OFFSET - 10);
	if (ui_opm(2, 3, &sys_param.lv2_low, &sys_param.lv3_high )) {
		printf("%4d %4d\r\n", sys_param.lv3_high, sys_param.lv2_low );
	}
	// printf("Lv3 Lv4  (-22dBm)\r\n\r\n");
	draw_2lv_range(3, 4, -20 - OPT_OFFSET + 10, -20 - OPT_OFFSET, -20 - OPT_OFFSET - 10);
	if (ui_opm(3, 4, &sys_param.lv3_low, &sys_param.lv4_high )) {
		printf("%4d %4d\r\n", sys_param.lv4_high, sys_param.lv3_low );
	}
	// printf("Lv4 Lv5  (-32dBm)\r\n\r\n");
	draw_2lv_range(4, 5, -30 - OPT_OFFSET + 10, -30 - OPT_OFFSET, -30 - OPT_OFFSET - 10);
	if (ui_opm(4, 5, &sys_param.lv4_low, &sys_param.lv5_high )) {
		printf("%4d %4d\r\n", sys_param.lv5_high, sys_param.lv4_low );
	}
	// printf("Lv5 Lv6  (-42dBm)\r\n\r\n");
	draw_2lv_range(5, 6, -40 - OPT_OFFSET + 10, -40 - OPT_OFFSET, -40 - OPT_OFFSET - 10);
	if (ui_opm(5, 6, &sys_param.lv5_low, &sys_param.lv6_high )) {
		printf("%4d %4d\r\n", sys_param.lv6_high, sys_param.lv5_low );
	}
	// printf("Lv6 Lv7  (-52dBm)\r\n\r\n");
	draw_2lv_range(6, 7, -50 - OPT_OFFSET + 10, -50 - OPT_OFFSET, -50 - OPT_OFFSET - 10);
	if (ui_opm(6, 7, &sys_param.lv6_low, &sys_param.lv7_high )) {
		printf("%4d %4d\r\n", sys_param.lv7_high, sys_param.lv6_low );
	}
	// if (ui_opm(4, 5)) {
	// 	g_adj_power.lv4_high = Lvn_OPM_ADC(4);
	// 	g_adj_power.lv5_low  = Lvn_OPM_ADC(5);
	// }
	// if (ui_opm(5, 6)) {

	// }
	// if (ui_opm(6, 7)) {

	// }
	show_opm();

}
// 一键校准
int do_adj(void *ptr, int argc, char **argv)
{
	if (argc < 2) {
		return -1;
	}
	switch (argv[1][0]) {
	case 'l': // adj ls
		one_key_ls();
		break;
	case 'o': // adj opm
		one_key_opm();
		break;
	default:
		return -1;
	}

	return 0;
}

int do_setenv(void *ptr, int argc, char **argv)
{
	if (argc < 3 ) {
		return 0;
	}

	_do_setenv(argv[1], argv[2]);
	return 0;
	if (0 == strcmp("sn", argv[1])) {
		strcpy(g_adj_power.sn, argv[2]);
	}


	else if (0 == strcmp("ch1-10-adc", argv[1])) {
		g_adj_power._adc1 = atoi(argv[2]);
	} else if (0 == strcmp("ch2-10-adc", argv[1])) {
		g_adj_power._adc2 = atoi(argv[2]);
	} else if (0 == strcmp("ch3-10-adc", argv[1])) {
		g_adj_power._adc3 = atoi(argv[2]);
	}

	else if (0 == strcmp("ch1-10-dac", argv[1])) {
		g_adj_power._dac1 = atoi(argv[2]);
	} else if (0 == strcmp("ch2-10-dac", argv[1])) {
		g_adj_power._dac2 = atoi(argv[2]);
	} else if (0 == strcmp("ch3-10-dac", argv[1])) {
		g_adj_power._dac3 = atoi(argv[2]);
	}


	else if (0 == strcmp("ch1-5-adc", argv[1])) {
		g_adj_power._5_adc1 = atoi(argv[2]);
	} else if (0 == strcmp("ch2-5-adc", argv[1])) {
		g_adj_power._5_adc1 = atoi(argv[2]);
	} else if (0 == strcmp("ch3-5-adc", argv[1])) {
		g_adj_power._5_adc1 = atoi(argv[2]);
	} else if (0 == strcmp("ch1-5-dac", argv[1])) {
		g_adj_power._5_dac1 = atoi(argv[2]);
	} else if (0 == strcmp("ch2-5-dac", argv[1])) {
		g_adj_power._5_dac1 = atoi(argv[2]);
	} else if (0 == strcmp("ch3-5-dac", argv[1])) {
		g_adj_power._5_dac1 = atoi(argv[2]);
	}


	else if (0 == strcmp("en-ch1", argv[1])) {
		g_adj_power.en_ch1 = atoi(argv[2]);
	} else if (0 == strcmp("en-ch2", argv[1])) {
		g_adj_power.en_ch2 = atoi(argv[2]);
	} else if (0 == strcmp("en-ch3", argv[1])) {
		g_adj_power.en_ch3 = atoi(argv[2]);
	}

	else if (0 == strcmp("wave-ch1", argv[1])) {
		g_adj_power._ch1wave = atoi(argv[2]);
	} else if (0 == strcmp("wave-ch2", argv[1])) {
		g_adj_power._ch2wave = atoi(argv[2]);
	} else if (0 == strcmp("wave-ch3", argv[1])) {
		g_adj_power._ch3wave = atoi(argv[2]);
	}
	return 0;
}

int do_save(void *ptr, int argc, char **argv)
{
	char strout[10];
	
	sys_param.lv1_low  = sys_param.lv2_low;
	sys_param.lv1_high = sys_param.lv2_high;
	sys_param.lv7_low = sys_param.lv7_high / 10;
	sys_param.ch1_wave = 1310;
	sys_param.ch2_wave = 1550;
	sys_param.ch3_wave = 1490;
	
	
	// Init_Overflow(&g_adj_power);
	{
		// TODO adj_power_flash 改成 struct overflow_limit_data
		struct adj_power_flash adj;

		adj.lv1_low  = sys_param.lv1_low;
		adj.lv1_high = sys_param.lv1_high;
		adj.lv2_low  = sys_param.lv2_low;
		adj.lv2_high = sys_param.lv2_high;
		adj.lv3_low  = sys_param.lv3_low;
		adj.lv3_high = sys_param.lv3_high;
		adj.lv4_low  = sys_param.lv4_low;
		adj.lv4_high = sys_param.lv4_high;
		adj.lv5_low  = sys_param.lv5_low;
		adj.lv5_high = sys_param.lv5_high;
		adj.lv6_low  = sys_param.lv6_low;
		adj.lv6_high = sys_param.lv6_high;
		adj.lv7_low  = sys_param.lv7_low;
		adj.lv7_high = sys_param.lv7_high;
		
		Init_Overflow(&adj);
	}
	
	snprintf(strout, sizeof(strout),"%d", sys_param.lv1_low);
	_do_setenv("lv1_low", strout);
	snprintf(strout, sizeof(strout),"%d", sys_param.lv2_low);
	_do_setenv("lv2_low", strout);
	snprintf(strout, sizeof(strout),"%d", sys_param.lv3_low);
	_do_setenv("lv3_low", strout);
	snprintf(strout, sizeof(strout),"%d", sys_param.lv4_low);
	_do_setenv("lv4_low", strout);
	snprintf(strout, sizeof(strout),"%d", sys_param.lv5_low);
	_do_setenv("lv5_low", strout);
	snprintf(strout, sizeof(strout),"%d", sys_param.lv6_low);
	_do_setenv("lv6_low", strout);
	snprintf(strout, sizeof(strout),"%d", sys_param.lv7_low);
	_do_setenv("lv7_low", strout);
	
	snprintf(strout, sizeof(strout),"%d", sys_param.lv1_high);
	_do_setenv("lv1_high", strout);
	snprintf(strout, sizeof(strout),"%d", sys_param.lv2_high);
	_do_setenv("lv2_high", strout);
	snprintf(strout, sizeof(strout),"%d", sys_param.lv3_high);
	_do_setenv("lv3_high", strout);
	snprintf(strout, sizeof(strout),"%d", sys_param.lv4_high);
	_do_setenv("lv4_high", strout);
	snprintf(strout, sizeof(strout),"%d", sys_param.lv5_high);
	_do_setenv("lv5_high", strout);
	snprintf(strout, sizeof(strout),"%d", sys_param.lv6_high);
	_do_setenv("lv6_high", strout);
	snprintf(strout, sizeof(strout),"%d", sys_param.lv7_high);
	_do_setenv("lv7_high", strout);
	
	snprintf(strout, sizeof(strout),"%d", sys_param.ch1_10_adc);
	_do_setenv("ch1_10_adc", strout);
	snprintf(strout, sizeof(strout),"%d", sys_param.ch2_10_adc);
	_do_setenv("ch2_10_adc", strout);
	snprintf(strout, sizeof(strout),"%d", sys_param.ch3_10_adc);
	_do_setenv("ch3_10_adc", strout);
	
	snprintf(strout, sizeof(strout),"%d", sys_param.ch2_10_dac);
	_do_setenv("ch1_10_dac", strout);
	snprintf(strout, sizeof(strout),"%d", sys_param.ch2_10_dac);
	_do_setenv("ch2_10_dac", strout);
	snprintf(strout, sizeof(strout),"%d", sys_param.ch2_10_dac);
	_do_setenv("ch3_10_dac", strout);
	
	Flash_Save();
	// env_2_system(sys_vals, ARRAY_SIZE(sys_vals));
}